package gui;

import java.awt.BorderLayout;
import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.List;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import javax.swing.JCheckBox;
import javax.swing.SwingConstants;
import javax.swing.JComboBox;
import javax.swing.JScrollPane;
import javax.swing.JList;

import algorithm.FinalTool;

import entities.Appointment;
import entities.Calendar;
import entities.Category;
import exceptions.IllegalAppointmentException;
import fachlogik.Administration;
import fachlogik.CategoriesCellRenderer;

import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.sql.Array;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class AppointmentDialog extends JFrame {

	private JPanel contentPane;

	private final JPanel contentPanel = new JPanel();
	private JTextField tf_name;
	private JTextField tf_begin;
	private JTextField tf_end;
	private JTextField tf_description;
	private JTextField tf_appPriority;
	private JComboBox cb_categories;
	private JCheckBox chckbxReschedulingAllowed;

	private DefaultComboBoxModel dcm;

	private SimpleDateFormat sf;

	private Appointment selectedAppointment;
	private CalendarWindow cw;
	private AppointmentDialog aw;
	private Calendar selectedCalendar;

	private Administration instance;
	private FinalTool tool;

	public AppointmentDialog(final Appointment a, final CalendarWindow cw) {

		addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent arg0) {
				cw.setAd(null);
			}
		});

		setDefaultCloseOperation(DISPOSE_ON_CLOSE);
		setBounds(100, 100, 450, 300);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		contentPane.setLayout(new BorderLayout(0, 0));
		setContentPane(contentPane);
		setResizable(false);

		aw = this;
		instance = cw.getInstance();

		try {
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		} catch (ClassNotFoundException | InstantiationException
				| IllegalAccessException | UnsupportedLookAndFeelException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		dcm = new DefaultComboBoxModel();
		selectedAppointment = a;
		this.cw = cw;
		selectedCalendar = cw.getSelectedCalendar();
		tool = new FinalTool();
		sf = new SimpleDateFormat("dd.MM.yyyy HH:mm");
		sf.setLenient(false);

		setTitle("Appointment");

		setLocationRelativeTo(null);
		setVisible(true);
		setBounds(100, 100, 320, 557);
		getContentPane().setLayout(new BorderLayout());
		contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
		getContentPane().add(contentPanel, BorderLayout.SOUTH);
		contentPanel.setLayout(null);
		{
			JPanel panel = new JPanel();
			getContentPane().add(panel, BorderLayout.CENTER);
			panel.setLayout(null);

			JLabel lblNewLabel_1 = new JLabel("Name:");
			lblNewLabel_1.setBounds(12, 11, 70, 15);
			panel.add(lblNewLabel_1);

			JLabel lblNewLabel = new JLabel("Description:");
			lblNewLabel.setBounds(12, 260, 148, 15);
			panel.add(lblNewLabel);

			JLabel lblNewLabel_2 = new JLabel("Begin:");
			lblNewLabel_2.setBounds(12, 48, 70, 15);
			panel.add(lblNewLabel_2);

			JLabel lblNewLabel_3 = new JLabel("End:");
			lblNewLabel_3.setBounds(12, 84, 70, 15);
			panel.add(lblNewLabel_3);

			JLabel lblNewLabel_4 = new JLabel("Rescheduling Allowed:");
			lblNewLabel_4.setBounds(12, 110, 160, 15);
			panel.add(lblNewLabel_4);

			JLabel lblNewLabel_5 = new JLabel("Category:");
			lblNewLabel_5.setBounds(12, 178, 70, 15);
			panel.add(lblNewLabel_5);

			JLabel lblNewLabel_6 = new JLabel("Appointment Priority");
			lblNewLabel_6.setBounds(12, 136, 148, 14);
			panel.add(lblNewLabel_6);

			tf_name = new JTextField();
			tf_name.setBounds(150, 11, 145, 25);
			panel.add(tf_name);
			tf_name.setColumns(10);

			tf_begin = new JTextField();
			tf_begin.setBounds(150, 43, 144, 25);
			panel.add(tf_begin);
			tf_begin.setColumns(10);

			tf_end = new JTextField();
			tf_end.setBounds(150, 79, 144, 25);
			panel.add(tf_end);
			tf_end.setColumns(10);

			chckbxReschedulingAllowed = new JCheckBox("");
			chckbxReschedulingAllowed
					.setVerticalAlignment(SwingConstants.BOTTOM);
			chckbxReschedulingAllowed.setBounds(204, 102, 23, 23);
			panel.add(chckbxReschedulingAllowed);

			tf_appPriority = new JTextField();
			tf_appPriority.setBounds(150, 136, 145, 25);
			panel.add(tf_appPriority);
			tf_appPriority.setColumns(10);

			cb_categories = new JComboBox(dcm);
			cb_categories.setRenderer(new CategoriesCellRenderer());
			cb_categories.setBounds(150, 170, 144, 30);
			panel.add(cb_categories);
			cbAktualisieren();

			JScrollPane scrollPane = new JScrollPane();
			scrollPane.setBounds(12, 290, 285, 191);
			panel.add(scrollPane);

			tf_description = new JTextField();
			scrollPane.setViewportView(tf_description);
			tf_description.setColumns(10);

			JButton btn_newCategory = new JButton("Add Category");
			btn_newCategory.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					if (cw.getCatWindow() == null) {
						CategoryWindow catWindow = new CategoryWindow(
								selectedCalendar, cw);
						cw.setCatWindow(catWindow);
						cbAktualisieren();
					}
				}
			});
			btn_newCategory.setBounds(12, 211, 148, 25);
			panel.add(btn_newCategory);
			
			if (selectedAppointment.getName() != null) {
				JButton btnReschedule = new JButton("Reschedule");
				btnReschedule.addActionListener(new ActionListener() {
					public void actionPerformed(ActionEvent arg0) {
						RescheduleWindow2 rw = new RescheduleWindow2(instance,
								a, aw);
						rw.setVisible(true);
						aw.setVisible(false);
					}
				});
				btnReschedule.setBounds(178, 235, 89, 23);
				panel.add(btnReschedule);
			}
			befuellen();
		}
		{
			JPanel buttonPane = new JPanel();
			buttonPane.setLayout(new FlowLayout(FlowLayout.RIGHT));
			getContentPane().add(buttonPane, BorderLayout.SOUTH);
			{
				JButton okButton = new JButton("OK");
				okButton.addActionListener(new ActionListener() {
					public void actionPerformed(ActionEvent e) {
						System.out.println("OK clicked");
						addOrEditAppointment();
					}
				});
				okButton.setActionCommand("OK");
				buttonPane.add(okButton);
				getRootPane().setDefaultButton(okButton);
			}
			{
				JButton cancelButton = new JButton("Cancel");
				cancelButton.addActionListener(new ActionListener() {
					public void actionPerformed(ActionEvent e) {
						cw.setAd(null);
						dispose();
					}
				});
				cancelButton.setActionCommand("Cancel");
				buttonPane.add(cancelButton);
			}
		}
	}

	public void cbAktualisieren() {
		dcm.removeAllElements();
		for (Category c : instance.getCalendarCategories(selectedCalendar)) {
			dcm.addElement(c);
		}
	}

	public void ausgewaehlteCategory(Category c) {
		cb_categories.setSelectedItem(c);
	}

	public void befuellen() {
		if (selectedAppointment != null) {
			if(selectedAppointment != null)
				tf_name.setText(selectedAppointment.getName());
			if (selectedAppointment.getBegin() != null)
				tf_begin.setText(sf.format(selectedAppointment.getBegin()));
			else
				tf_begin.setText(sf.format(cw.getSelectedDate()));
			if (selectedAppointment.getEnd() != null)
				tf_end.setText(sf.format(selectedAppointment.getEnd()));
			tf_description.setText(selectedAppointment.getDescription());
			tf_appPriority.setText(String.valueOf(selectedAppointment
					.getAppointmentPriority()));
			chckbxReschedulingAllowed.setSelected(selectedAppointment
					.getReschedulingAllowed());
			if (selectedAppointment.getCategory() != null)
				cb_categories
						.setSelectedItem(selectedAppointment.getCategory());
		}
	}

	public Administration getInstance() {
		return instance;
	}

	public void addOrEditAppointment() {

		String name = tf_name.getText();
		String beginn = tf_begin.getText();
		String ende = tf_end.getText();
		String description = tf_description.getText();
		String appPriority = tf_appPriority.getText();
		Category category = (Category) cb_categories.getSelectedItem();
		boolean isAllowed = chckbxReschedulingAllowed.isSelected();

		if (!name.equals("") && !beginn.equals("") && !ende.equals("")
				&& !appPriority.equals("")) {
			try {
				int appPriorityInt = Integer.parseInt(appPriority);
				// Abfragen ob die Priority richtig angegeben wurde
				if (appPriorityInt >= 1 && appPriorityInt <= 5) {

					// wenn rescheduling erlaubt ist, muss das Appointment einer
					// Kategorie zugewiesen sein
					if (isAllowed && category == null) {
						JOptionPane.showMessageDialog(null,
								"Please choose a category!");
						return;
					}
					try {
						Date anfang = sf.parse(beginn);
						Date end = sf.parse(ende);
						if (anfang.before(end)) {
							if (category != null) {

								int cat_hours_start = category.getAnfangszeit()
										.getHours();
								int cat_min_start = category.getEndzeit()
										.getMinutes();

								int cat_hours_end = category.getEndzeit()
										.getHours();
								int cat_min_end = category.getEndzeit()
										.getMinutes();

								int app_hours_start = anfang.getHours();
								int app_min_start = anfang.getMinutes();

								int app_hours_end = end.getHours();
								int app_min_end = end.getMinutes();

								// Category Start: 07:15
								// Ende: 16:16

								// Appointment Start: 08:26
								// Ende: 16:50

								boolean ok = false;
								if (cat_hours_start < app_hours_start) {
									if (cat_hours_end >= app_hours_end) {
										if (cat_hours_end == app_hours_end) {
											if (cat_min_end >= app_min_end)
												ok = true;
											else
												ok = false;
										} else
											ok = true;
									}
								}
								if (cat_hours_start == app_hours_start) {
									if (cat_min_start <= app_min_start) {
										if (cat_hours_end >= app_hours_end) {
											if (cat_hours_end == app_hours_end) {
												if (cat_min_end >= app_min_end)
													ok = true;
												else
													ok = false;
											} else
												ok = true;
										}
									}
								}
								if (!ok) {
									JOptionPane
											.showMessageDialog(
													null,
													"The start and end of the appointment is not in the"
															+ " timespan, which the category defines!");
									return;
								}
							}
							selectedAppointment
									.setReschedulingAllowed(isAllowed);
							selectedAppointment.setName(name);
							selectedAppointment.setBegin(anfang);
							selectedAppointment.setEnd(end);
							selectedAppointment.setDescription(description);
							selectedAppointment.setCategory(category);
							selectedAppointment.setCalendar(selectedCalendar);
							selectedAppointment
									.setAppointmentPriority(appPriorityInt);

							if (tool.overlap(selectedAppointment).size() == 0) {
								System.out.println("overlap-size = 0");
								instance.addOrEditAppointment(selectedAppointment);
								cw.appointmentsAktualisieren();
								cw.setAd(null);
								dispose();
							} else if (tool.overlap(selectedAppointment).size() == 1
									&& tool.overlap(selectedAppointment).get(0)
											.getId() == selectedAppointment
											.getId()) {
								System.out.println("overlap-size = 1 && ....");
								instance.addOrEditAppointment(selectedAppointment);
								cw.appointmentsAktualisieren();
								cw.setAd(null);
								dispose();
							} else {
								System.out.println("....");
								JOptionPane
										.showMessageDialog(
												null,
												"Please check calendar and change parameters accordingly",
												"Overlapping Appointment!", 0);
							}

						} else
							JOptionPane
									.showMessageDialog(null,
											"The end of the appointment is before the beginning!");
					} catch (ParseException e1) {
						JOptionPane.showMessageDialog(null,
								"Enter dates thusly: dd.mm.yyyy hh:mm");
						// e1.printStackTrace();
					} catch (IllegalAppointmentException e) {
						JOptionPane
								.showMessageDialog(null,
										"End of appointment must not be before beginning!");
						// e.printStackTrace();
					}
				} else
					JOptionPane
							.showMessageDialog(null,
									"The appointment priority must be a number between 1 and 5");
			} catch (NumberFormatException nfe) {
				JOptionPane.showMessageDialog(null,
						"Priority is defined only by numbers!");
			}
		} else {
			JOptionPane.showMessageDialog(null, "Some fields are left blank!");
		}
	}

	public CalendarWindow getCW() {
		return cw;
	}

}
